---------------------------------------------------------------------------------- 
-- Engineer: David McNamara
-- 
-- Module Name:    uartRadioCtrl - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: Is the top lelvel compoent for uart transmission to the radio

----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;

use ascii_slv.all;                      --use ascii to binary package

entity uartRadioCtrl is
  port (clk            : in  std_logic;
        rst            : in  std_logic;
        pushbuttons    : in  std_logic_vector(3 downto 0);
        sliderswitches : in  std_logic_vector(7 downto 0);
        mhz            : out integer range 0 to 9999;
        khz            : out integer range 0 to 9999;
        vol            : out integer range 0 to 99;
        det            : out std_logic;
        bws            : out integer range 0 to 15;
        tx             : out std_logic := '1');
end uartRadioCtrl;

architecture Behavioral of uartRadioCtrl is
  --uarrt related variables
  signal tx_start : std_logic                    := '0';
  signal tx_done  : std_logic;
  signal data     : std_logic_vector(7 downto 0) := x"00";

  --frequency value in ascii array
  type   frq_ascii is array (0 to 7) of std_logic_vector(7 downto 0);
  signal frq_ascii_value : frq_ascii;

  --total ascii string to be sent out
  type   total_ascii is array (0 to 43) of std_logic_vector(7 downto 0);
  signal uart_text : total_ascii;

  --ascii variables used for radio setttings
  signal vol_ascii_value_p1, vol_ascii_value_p2, det_mode, bws_p1, bws_p2 : std_logic_vector(7 downto 0);
  signal buttons                                                          : std_logic_vector(3 downto 0);

begin

  buttons <= pushbuttons;               -- Debounced in top level

  --uart transmit component
  uart_tx_U : entity work.uart_tx
    port map(clk      => clk,
             reset    => rst,
             tx_start => tx_start,
             tx_done  => tx_done,
             tx       => tx,
             data_in  => data);

  process(clk)
    variable c   : integer range 0 to 43;  --counter for ascii string 
    variable tmp : std_logic := '0';       --signaling variable
  begin
    if rising_edge(clk) then
      if (buttons(1) = '1') then           --button used to send out string
        tmp := '1';
      end if;

      if tmp = '1' then                 --if button has been pressed
        if (tx_start = '0' and c < 43) then  --transmit all 43 characters
          tx_start <= '1';              --turn on uart transmitter
          data     <= uart_text(c);     --send current character to transmitter
          c        := c+1;              --increment the counter
          
        elsif (tx_done = '1') then      --transmission of charater is complete
          tx_start <= '0';              --send tx_start low
          if c = 43 then                --if all characters have been sent
            tmp := '0';                 --set transmiion signal to 0
            c   := 0;                   --set counter to 0
          end if;
        end if;
      end if;
    end if;
  end process;


  process(clk, rst)
    variable input_number : std_logic_vector(7 downto 0);
  begin
    if rst = '1' then
      --reset values
      frq_ascii_value    <= (others => (ascii_to_slv('0')));
      vol_ascii_value_p1 <= (ascii_to_slv('0'));
      vol_ascii_value_p2 <= (ascii_to_slv('0'));
      det_mode           <= (ascii_to_slv('0'));
    elsif rising_edge(clk) then
      if (buttons(2) = '1') then  --if button(2) is hit load current sliderswitch value
        --translate switch value to ascii value
        case sliderswitches(3 downto 0) is
          when "0000" =>
            input_number := x"30";
          when "0001" =>
            input_number := x"31";
          when "0010" =>
            input_number := x"32";
          when "0011" =>
            input_number := x"33";
          when "0100" =>
            input_number := x"34";
          when "0101" =>
            input_number := x"35";
          when "0110" =>
            input_number := x"36";
          when "0111" =>
            input_number := x"37";
          when "1000" =>
            input_number := x"38";
          when "1001" =>
            input_number := x"39";
          when others =>
            input_number := x"30";
        end case;

        --if frequency value is being updated
        if sliderswitches(7) = '1' then
          frq_ascii_value(to_integer(unsigned(sliderswitches(6 downto 4)))) <= input_number;
        end if;

        --if other radio parameters are bing updated
        if sliderswitches(7) = '0' then
          case sliderswitches(6 downto 5) is
            when "00" =>
              vol_ascii_value_p1 <= input_number;
            when "01" =>
              vol_ascii_value_p2 <= input_number;
            when "10" =>
              det_mode <= input_number;
            when others =>
              bws_p1 <= input_number;
          end case;
        end if;
      end if;
    end if;
  end process;

  --fill string with values
  uart_text(0) <= ascii_to_slv('S');
  uart_text(1) <= ascii_to_slv('A');
  uart_text(2) <= ascii_to_slv('0');
  uart_text(3) <= ascii_to_slv(' ');
  uart_text(4) <= ascii_to_slv('1');
  uart_text(5) <= ascii_to_slv('^');
  uart_text(6) <= ascii_to_slv('\');

  uart_text(7)  <= ascii_to_slv('V');
  uart_text(8)  <= ascii_to_slv('O');
  uart_text(9)  <= ascii_to_slv('L');
  uart_text(10) <= ascii_to_slv(' ');
  uart_text(11) <= vol_ascii_value_p1;
  uart_text(12) <= vol_ascii_value_p2;
  uart_text(13) <= ascii_to_slv('^');
  uart_text(14) <= ascii_to_slv('\');

  uart_text(15) <= ascii_to_slv('F');
  uart_text(16) <= ascii_to_slv('R');
  uart_text(17) <= ascii_to_slv('Q');
  uart_text(18) <= ascii_to_slv(' ');
  uart_text(19) <= frq_ascii_value(7);
  uart_text(20) <= frq_ascii_value(6);
  uart_text(21) <= frq_ascii_value(5);
  uart_text(22) <= frq_ascii_value(4);
  uart_text(23) <= ascii_to_slv('.');
  uart_text(24) <= frq_ascii_value(3);
  uart_text(25) <= frq_ascii_value(2);
  uart_text(26) <= frq_ascii_value(1);
  uart_text(27) <= frq_ascii_value(0);
  uart_text(28) <= ascii_to_slv('^');
  uart_text(29) <= ascii_to_slv('\');


  uart_text(30) <= ascii_to_slv('D');
  uart_text(31) <= ascii_to_slv('E');
  uart_text(32) <= ascii_to_slv('T');
  uart_text(33) <= ascii_to_slv(' ');
  uart_text(34) <= det_mode;
  uart_text(35) <= ascii_to_slv('^');
  uart_text(36) <= ascii_to_slv('\');

  uart_text(37) <= ascii_to_slv('B');
  uart_text(38) <= ascii_to_slv('W');
  uart_text(39) <= ascii_to_slv('S');
  uart_text(40) <= ascii_to_slv(' ');
  uart_text(41) <= bws_p1;
  uart_text(42) <= ascii_to_slv('^');
  uart_text(43) <= ascii_to_slv('\');

  --convert values to intgers for display purposes
  mhz <= to_integer(unsigned(frq_ascii_value(7)(3 downto 0)))*1000+to_integer(unsigned(frq_ascii_value(6)(3 downto 0)))*100+to_integer(unsigned(frq_ascii_value(5)(3 downto 0)))*10+to_integer(unsigned(frq_ascii_value(4)(3 downto 0)))*1;
  khz <= to_integer(unsigned(frq_ascii_value(3)(3 downto 0)))*1000+to_integer(unsigned(frq_ascii_value(2)(3 downto 0)))*100+to_integer(unsigned(frq_ascii_value(1)(3 downto 0)))*10+to_integer(unsigned(frq_ascii_value(0)(3 downto 0)))*1;
  vol <= to_integer(unsigned(vol_ascii_value_p1(3 downto 0)))*10+to_integer(unsigned(vol_ascii_value_p2(3 downto 0)));
  bws <= to_integer(unsigned(bws_p1(3 downto 0)));

  with det_mode(3 downto 0) select
    det <=
    '1' when "0010",                    -- FM
    '0' when others;                    -- AM

  
end Behavioral;

